/*
Copyright DAUPHIN Maxime 2005

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
http://www.gnu.org/licenses/gpl.txt
*/
#ifndef __DC_H__
#define __DC_H__

#include "Gui.h"

namespace Gui {

class Point
{
	POINT m_point;
public:
	int x;
	int y;
	Point(int x = 0, int y = 0) : x(x), y(y) {}
	Point(const Point &p) { x = p.x; y = p.y; }
	Point(const POINT &p) { x = p.x; y = p.y; }
	operator POINT(void) const
	{ 
		POINT point;
		point.x = x; 
		point.y = y; 
		return point; 
	}
	bool operator ==(const Point &p) const { return ( ( x == p.x ) && ( y == p.y ) ); }
	bool operator !=(const Point &p) const { return !( p == *this ) ; }
};

class Rect
{
	RECT	m_rect;
public:
	Point t;
	Point d;
	Rect(int x=0, int y=0, int cx=0, int cy=0) { t.x = x; t.y = y; d.x = cx; d.y = cy; }
	Rect(const Point &t, const Point &d) : t(t), d(d) {}
	Rect(RECT &rect) { t.x = rect.left; t.y = rect.top; d.x = rect.right; d.y = rect.bottom; }
	int getWidth() const { return ( d.x - t.x ); }
	int getHeight() const { return ( d.y - t.y ); }
	operator LPRECT(void) const
	{
		::SetRect( (LPRECT)&m_rect, t.x, t.y, d.x, d.y );
		return (LPRECT)&m_rect;
	}
	bool isIn(const Point point)
	{
		if ( point.x < t.x || point.x > (t.x+d.x) )
			return false;
		if ( point.y < t.y || point.y > (t.y+d.y) )
			return false;
		return true;
	}
	bool operator ==(const Rect &r) const { return ( ( r.t == t ) && ( r.d == d ) ); }
	bool operator !=(const Rect &r) const { return !( r == *this ) ; }

};

class Color
{
	void normalize() 
	{
		if ( r > 255 ) r = 255;
		if ( g > 255 ) g = 255;
		if ( b > 255 ) b = 255;
		if ( r < 0 ) r = 0;
		if ( g < 0 ) g = 0;
		if ( b < 0 ) b = 0;
	}
public:
	int r;
	int g;
	int b;
	Color(int r=0x00, int g=0x00, int b=0x00) : r(r), g(g), b(b) {}
	Color(const Color &c) : r(c.r), g(c.g), b(c.b) {}
	Color(COLORREF colorRef) 
	{ 
		r = GetRValue(colorRef);
		g = GetGValue(colorRef);
		b = GetBValue(colorRef);
	}
	operator COLORREF(void) const { return RGB(r,g,b); }
	bool operator ==(const Color &c) const { return ( ( r == c.r ) && ( g == c.g ) &&( b == c.b ) ); }
	bool operator !=(const Color &c) const { return !( c == *this ) ; }
	Color operator-(const Color &c) const { return Color( r - c.r, g - c.g, b - c.b ); }
	//Color operator-(const Color &c) const { return Color( c.r - r, c.g - g, c.b - b ); }
	Color operator+(const Color &c) const { return Color( r + c.r, g + c.g, b + c.b ); }
	Color& operator+=(const Color &c) { r += c.r; g += c.g; b += c.b; normalize(); return (*this); }
	Color operator /(const int v) { return Color( r/v, g/v, b/v ); }
};

class Dc
{
protected:
	Wnd *m_pWnd;
	HDC	m_hDC;
	Dc(void);
public:
	Dc(Wnd *pWnd);
	Dc(HDC hDC);
	virtual ~Dc(void);
	operator HDC(void) const { assert(m_hDC); return m_hDC; }
	virtual void textOut(int x, int y, STRING str);
	virtual void fillRect( const Rect& rect, const Color &color);
	virtual int setBkMode( const int iBkMode );
	virtual bool drawIcon( Point point, HICON hIcon );
	virtual int drawText( const STRING string, const Rect rect, UINT uFormat );
	virtual bool drawGradient( const Rect &rect, const Color &start, const Color &end);
	virtual Dc* createCompatibleDc();
	virtual HGDIOBJ selectObject(HGDIOBJ hObject);
	virtual void bitBlt( int x, int y, int nWidth, int nHeight, Dc* pSrcDC, int xSrc, int ySrc, DWORD dwRop );
	virtual void stretchBlt( const Rect &dest, const Rect &ori, Dc* pSrcDC, DWORD dwRop );
};

class PaintDc : public Dc
{
	PAINTSTRUCT m_ps;
public:
	PaintDc(Wnd *pWnd);
	virtual ~PaintDc(void);
};

}; //namespace Gui

#endif //#define __DC_H__
